package ltd.bugs.cute.common.reflect;

import java.lang.annotation.Annotation;
import java.net.URL;
import java.util.HashSet;
import java.util.Set;

import org.reflections.Reflections;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import ltd.bugs.cute.common.util.PropertyUtil;

public class ReflectionsUtils {

  private static Logger logger = LoggerFactory.getLogger(ReflectionsUtils.class);
  // 框架自身的基础包路径
  public static final String CUTE_BASE_PACKAGE = "ltd.bugs";
  private static final Set<URL> scanUrls = new HashSet<URL>();

  // 初始化spi扫描的包路径过滤器
  static {
    String spiScanPackage = PropertyUtil.getDefaultConfig("cute.scan.packages", String.class);

    boolean hasIncludeBasePackage = false;
    if (!StringUtils.isEmpty(spiScanPackage)) {
      logger.info("scan package is {}", spiScanPackage);
      String[] packages = spiScanPackage.split(",");
      for (String packagePath : packages) {
        scanUrls.addAll(ClasspathHelper.forPackage(packagePath));
        if (CUTE_BASE_PACKAGE.equals(packagePath)) {
          hasIncludeBasePackage = true;
        }
      }
    }

    if (!hasIncludeBasePackage) {
      // 增加默认的路径
      scanUrls.addAll(ClasspathHelper.forPackage(CUTE_BASE_PACKAGE));
    }
  }

  public static <T> Set<Class<? extends T>> getSubTypesOf(Class<T> type) {
    Reflections reflections = new Reflections(new ConfigurationBuilder().setUrls(scanUrls));
    return reflections.getSubTypesOf(type);
  }

  public static <T> Set<Class<?>> getTypesAnnotatedWith(Class<? extends Annotation> type) {
    Reflections reflections = new Reflections(new ConfigurationBuilder().setUrls(scanUrls));
    return reflections.getTypesAnnotatedWith(type);
  }
}
